home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok59.lha
/
AmokEd_V1.02b
/
txt
/
ApplDemo.mod
< prev
next >
Wrap
Text File
|
1993-08-15
|
10KB
|
373 lines
(*(***********************************************************************
:Program. ApplDemo.mod
:Contents. AmokEd Applications-Demo
:Author. Hartmut Goebel [hG]
:Language. Oberon
:Translator. Amiga Oberon V2.00
:Imports. Printf (Volker Rudolph)
:History. V1.0 09 Mar 1991 Hartmut Goebel
:History. V1.1 14 Jul 1991 [hG] +Test für XPingPong
:History. V1.2 12 Oct 1991 [hG] AEd0 und AEd1-Typen sind jetzt drin
:Date. 19 Oct 1991 03:35:57
:Remark. Jetzt mit besserer Dokumentation!
:Usage. AEd: execute (run appldemo $rexxport)
***********************************************************************)*)
(*
* Dient als Beipiel für eine AmokEd-Applikation und zum Testen der
* AEdAppl-Befehle.
* Alles, was kein AEdAppl-Befehl ist, wird mit dem title-Befehl in
* Titel des Editors angezeigt.
*
* Dieses Programm hat noch viele kleine Unsauberheiten im Bereich
* des Port/Message-Handlings (PutMsg etc.), aber ich hatte keine Zeit
* und Lust mehr, sie alle zu bereinigen.
*
*)
MODULE ApplDemo;
IMPORT
Printf, io, NoGuru, Break,
arg: Arguments,
d : Dos,
e : Exec,
eAD: EdApplDefs,
lst: Lists,
ol : OberonLib,
req: Requests,
arx: ARexx,
rx : Rexx,
str: Strings,
sys: SYSTEM;
TYPE
String = ARRAY 256 OF CHAR;
StringPtr = POINTER TO String;
Host = RECORD (lst.Node)
name: StringPtr;
END;
HostPtr = POINTER TO Host;
CONST
ApplDemo = "ApplDemoPort";
CantCreateArgstring = "Can't Create Argstring\n";
NewText = "NewText";
numActivePings = 5;
Announce = "appladd ApplDemo ApplDemoPort";
VAR
MyPort: e.MsgPort;
Me: d.ProcessPtr;
rmptr: arx.RexxMsgPtr;
string: e.STRPTR;
test, PortAdded: BOOLEAN;
HisPortName: ARRAY 50 OF CHAR; (* muß reichen *)
pingnum: INTEGER;
PingPongField: POINTER TO eAD.XPingPong;
HostList: lst.List;
(*
PROCEDURE IsElement(VAR list: e.List; e: e.NodePtr): BOOLEAN;
VAR
n: e.MinListPtr;
BEGIN
n := list.head;
WHILE n.succ # NIL DO
IF e = n THEN RETURN TRUE; END;
n := n.succ;
END;
RETURN FALSE;
END IsElement;
*)
(*
* doRexx schickt die Msg an den ZielPort
*
* Hier sind einige Parameter gegeben, die für diese Demo eigentlich
* unnötig sind. Z.B. <modifier> und <port>, da wir nur mit einem Port
* kommunizieren und immer die gleichen <modifier> mitgeben.
*
*)
PROCEDURE doRexx(txt: e.ADDRESS; modifier: SHORTSET;
type: INTEGER;
port: ARRAY OF CHAR;
arg0, arg1: LONGINT); (* demo cmds have only 1 arg! *)
VAR
rxMsg,cmdMsg: arx.RexxMsgPtr;
ARexxPort: e.MsgPortPtr;
BEGIN
rxMsg := arx.CreateRexxMsg(sys.ADR(MyPort),NIL,sys.ADR(ApplDemo));
IF rxMsg#NIL THEN
(* okay, jetzt können wir die Felder füllen *)
rxMsg.action.command := arx.comm; (* msg ist Command *)
rxMsg.action.modifier := modifier; (* paramter! *)
rxMsg.args[0] := arg0; (* command to be executed *)
rxMsg.args[1] := arg1; (* argument for that command *)
rxMsg.args[eAD.TextSlot] := txt; (* Text for witch the Msg is *)
IF type = 0 THEN
rxMsg.node.node.name := eAD.idAEd0; (* ID for Msg-Type *)
ELSE
rxMsg.node.node.name := eAD.idAEd1; (* ID for Msg-Type *)
END;
e.Forbid;
ARexxPort := e.FindPort(port); (* Port suchen *)
IF ARexxPort#NIL THEN
e.PutMsg(ARexxPort,rxMsg); (* msg schicken *)
e.Permit;
LOOP
e.WaitPort(sys.ADR(MyPort));
cmdMsg := e.GetMsg(sys.ADR(MyPort));
WHILE cmdMsg # NIL DO
io.WriteString("Results:");
io.WriteInt(cmdMsg.result1,4); (* results ausgeben *)
io.WriteInt(cmdMsg.result2,4);
io.WriteLn;
IF rxMsg = cmdMsg THEN (* eigene Msg zurück -> fertig *)
EXIT; END;
e.ReplyMsg(cmdMsg); (* ansonsten unbearbeitet zurück *)
cmdMsg := e.GetMsg(sys.ADR(MyPort));
END;
END; (* LOOP *)
ELSE; (* IF ARexxPort#NIL *)
e.Permit;
io.WriteString("Port not found!!\n"); HALT(20);
END;
arx.DeleteRexxMsg(rxMsg);
ELSE
io.WriteString("CreateRexxMsg failed\n");
HALT(20);
END;
END doRexx;
PROCEDURE NewHost(name: StringPtr): BOOLEAN;
VAR
host: HostPtr;
len: INTEGER;
BEGIN
NEW(host);
IF host # NIL THEN
len := str.Length(name^)+1;
ol.New(host.name,len);
IF host.name # NIL THEN
e.CopyMem(name^,host.name^,len);
lst.AddTail(HostList,host);
RETURN TRUE;
END;
DISPOSE(host);
END;
RETURN FALSE;
END NewHost;
PROCEDURE Start;
VAR
rxArg: StringPtr;
BEGIN
(*
* Hier wäre es sinnvoll, zu testen, ob die gleiche Applikation schon
* läuft. Wenn ja, bekommt diese eine Msg zu schicken, in der mitgeteilt
* wird, sie soll auf noch einen Port reagieren, uns wir brechen ab.
* In solch einem Fall müßen Öffnen und Schließen mitgezählt werden!
*)
(* Initialize our message port *)
IF arx.InitPort(sys.ADR(MyPort),sys.ADR(ApplDemo)) = -1 THEN
io.WriteString("Can't InitPort\n");
HALT(20);
END;
(* same PortName exists? => same Appl *)
e.Forbid();
IF e.FindPort(ApplDemo) # NIL THEN
doRexx(NIL,SHORTSET{},1,ApplDemo,sys.ADR(NewText),sys.ADR(HisPortName));
(* e.Permid(); nicht nötig, wg. e.WaitPort() in doRexx *)
(*
* eben nicht, wiel monentan die andere abbricht!!
*
HALT(0);
*)
WHILE e.FindPort(ApplDemo) # NIL DO
d.Delay(100); END;
END;
PortAdded := TRUE;
e.AddPort(sys.ADR(MyPort)); (* Make the port public *)
lst.Init(HostList);
IF NOT NewHost(sys.ADR(HisPortName)) THEN
io.WriteString("No memory!\n");
HALT(20);
END;
(*
* Appl-Anmeldung an AmokEd schicken
*
* Bsp. für Typ AEd0 (ein StringPtr in args[0])
* Der String wird geparset, darum brauchen wir einen Argstring
*
* AEd kenn uns noch nicht, daher der FindPort()
*)
rxArg := arx.CreateArgstring(sys.ADR(Announce),sys.SIZE(Announce));
IF rxArg = NIL THEN
io.WriteString(CantCreateArgstring);
HALT(20);
END;
e.Forbid();
IF e.FindPort(HisPortName) # NIL THEN
doRexx(NIL,SHORTSET{},0,HisPortName,rxArg,0);
(* e.Permid(); nicht nötig, wg. e.WaitPort() in doRexx *)
arx.DeleteArgstring(rxArg);
ELSE
e.Permit();
arx.DeleteArgstring(rxArg);
io.WriteString("Port not found!!\n");
HALT(20);
END;
ol.MemReqs := LONGSET{e.public};
NEW(PingPongField);
IF PingPongField = NIL THEN
io.WriteString("No Memory!");
HALT(20);
END;
pingnum := eAD.NumExtPingPong;
REPEAT
DEC(pingnum);
PingPongField[pingnum].line := -1;
UNTIL pingnum = 0;
PingPongField[0].line := 2; PingPongField[0].pos := 0;
PingPongField[1].line := 4; PingPongField[1].pos := 4;
PingPongField[2].line := 4; PingPongField[2].pos := 20;
PingPongField[3].line := 7; PingPongField[3].pos := 13;
PingPongField[4].line := 9; PingPongField[4].pos := 13;
END Start;
PROCEDURE CloseDown;
VAR
n, s: e.MessagePtr;
BEGIN
io.WriteString("Closing\n");
IF PortAdded THEN
e.RemPort(sys.ADR(MyPort));
END;
(*
e.Forbid();
n := MyPort.msgList.head;
WHILE n.node.succ # NIL DO
s := n.node.succ;
IF n.replyPort # sys.ADR(MyPort) THEN
e.Remove(n);
e.ReplyMsg(n);
END;
n := s;
END;
e.Permit;
*)
arx.FreePort(sys.ADR(MyPort));
END CloseDown;
(*
PROCEDURE TestArgs;
VAR
args: INTEGER;
b: String;
BEGIN
args := arg.NumArgs();
io.WriteInt(args,4);
WHILE args > 0 DO
arg.GetArg(args,b);
io.WriteString(b); io.WriteLn;
DEC(args);
END;
END TestArgs;
*)
BEGIN
(* Will genau passende Anzahl Parameter *)
IF arg.NumArgs() # eAD.numNotifyArgsAEd1 THEN
io.WriteString("Bad Args\n");
HALT(20);
END;
arg.GetArg(1,HisPortName); (* Der Name des ZielPorts *)
Start;
io.WriteString("started\n");
LOOP
e.WaitPort(sys.ADR(MyPort));
rmptr := e.GetMsg(sys.ADR(MyPort));
IF arx.IsRexxMsg(rmptr) THEN
e.ReplyMsg(rmptr);
EXIT;
ELSIF (rmptr.node.node.name=eAD.idAEd0)
OR (rmptr.node.node.name=eAD.idAEd1) THEN
(*
* AmokEd sendet nur Typ AEd0, aber ApplDemo schickt AEd1
*)
rmptr.result1 := 0;
rmptr.result2 := NIL;
IF (rmptr.action.command = arx.close) THEN
e.ReplyMsg(rmptr);
EXIT;
END;
IF rmptr.args[0] = NIL THEN
rmptr.result1 := 10;
rmptr.result2 := NIL;
ELSE
string := rmptr.args[0];
(*
* Die Strings werden nicht geparset, darum brauchen wir auch
* keinen Argstring
*)
IF str.NCStrCmp(string^,"PINGPING") = 0 THEN
doRexx(rmptr.args[eAD.TextSlot],SHORTSET{},1,HisPortName,
sys.ADR("XPING"),PingPongField);
ELSIF str.NCStrCmp(string^,"NEXTPING") = 0 THEN
doRexx(rmptr.args[eAD.TextSlot],SHORTSET{},1,HisPortName,
sys.ADR("XPONG"),pingnum);
INC(pingnum);
IF pingnum = numActivePings THEN pingnum := 0; END;
ELSIF string^ = NewText THEN
HALT(5);
(*
* irgendwie so, ich hab aber keine Lust mehr, das
* jetzt in alle Einzelhaiten zu programmieren
*
IF NOT NewHost(rmptr.args[1]) THEN
rmptr.result1 := edE.cmdSevere;
rmptr.result2 := edE.NoMemory;
END;
*)
ELSE
doRexx(rmptr.args[eAD.TextSlot],SHORTSET{},1,HisPortName,
sys.ADR("title"),rmptr.args[0]);
(* an AmokEd schicken *)
END;
END;
END;
e.ReplyMsg(rmptr);
END; (* LOOP *)
CLOSE
CloseDown;
END ApplDemo.